Coder 灰桑

Stay Foolish, Always Foolish

SwiftUI 如何监听 @State 变更

几种实现方式

import Combine

struct ObserveStateChange: View {
    var body: some View {
        VStack(spacing: 32) {
            Solution1().padding().background(Color.red)
            Solution2().padding().background(Color.yellow)
            Solution3().padding().background(Color.green)
        }
    }

    /// 1
    struct Solution1: View {
        @State var location: String = ""

        var body: some View {
            let binding = Binding<String>(get: {
                self.location
            }, set: {
                self.location = $0
                // do whatever you want here
                print("Solution1 \($0)")
            })

            TextField("Search Location", text: binding)
        }
    }

    /// 2
    struct Solution2: View {
        @State var location: String = ""

        var body: some View {
            TextField("Search Location", text: $location)
                .onReceive(Just(location)) { print("Solution2 \($0)") }
        }
    }

    /// 3
    struct Solution3: View {
        @State var location: String = ""

        var body: some View {
            TextField("Search Location", text: $location.onChange { print("Solution3 \($0)") })
        }
    }
    
		/// 4
    struct Solution4: View {
        @State var location: String = ""

        var body: some View {
            TextField("Search Location", text: $location)
             .onChange(of: location) { 
                 print("Solution4 \($0)")   
            }
        }
    }
}

extension Binding {
    func onChange(_ handler: @escaping (Value) -> Void) -> Binding<Value> {
        Binding(
            get: { self.wrappedValue },
            set: { newValue in
                self.wrappedValue = newValue
                handler(newValue)
            }
        )
    }
}

1⃣️使用定义一个 Binding 属性,通过 get 和 set 来变更 @State。

2⃣️通过 onReceive 监听 Just Publisher 包装 State 促发的事件

3⃣️通过拓展 Binding 添加一个方法实现方法一的类似实现,包裹一层 Binding 来将变更回调出去。

4⃣️iOS14 支持的新特性。

经过实践推荐使用3⃣️或者4⃣️。

🔙  Xcode 项目多环境配置
SwiftUI - 开发图片模糊的 MAC 小应用  🔜